﻿using System;
using System.Collections.Generic;
using System.Linq;
using DAL;

namespace BLL
{
    public class CourseBll
    {
        private readonly Course _course;

        /// <summary>
        /// 根据课程ID构造CourseBll对象
        /// </summary>
        /// <param name="id">课程在数据库中的ID</param>
        /// <param name="visit">是否增加访问</param>
        public CourseBll(int id, bool visit)
        {
            using (var context = new ModelContainer())
            {
                _course = context.Courses
                    .Include("Teacher")
                    .Include("Chats")
                    .Include("Chats.ChatReplys")
                    .Include("Helps")
                    .Include("Helps.HelpReplys")
                    .Include("CoursePlaces")
                    .Include("CourseInfo")
                    .SingleOrDefault(course => course.ID == id);
                if (!visit || _course == null) return;
                _course.CourseInfo.Visits++;
                _course.MarkAsModified();
                context.Courses.ApplyChanges(_course);
                context.SaveChanges();
                _course.AcceptChanges();
            }
        }

        /// <summary>
        /// 返回课程对象
        /// </summary>
        /// <returns>课程对象</returns>
        public Course GetCourse()
        {
            return _course;
        }

        /// <summary>
        /// 返回同名课程
        /// </summary>
        /// <param name="count">需要的数量</param>
        /// <param name="total">总数</param>
        /// <returns>结果</returns>
        public List<Course> GetSameNameCourses(int count, out int total)
        {
            using (var context = new ModelContainer())
            {
                var result = context.Courses
                    .Include("Teacher")
                    .Include("CourseInfo")
                    .Where(course =>
                        course.CourseName == _course.CourseName
                        && course.ID != _course.ID)
                    .ToList();
                total = result.Count;
                return result.Take(count).ToList();
            }
        }

        /// <summary>
        /// 根据指定页容量返回求助信息
        /// </summary>
        /// <param name="page">页码</param>
        /// <param name="pageSize">每页容量</param>
        /// <param name="pageCount">返回总页数</param>
        /// <returns>求助信息列表</returns>
        public List<Help> GetHelps(int page, int pageSize, out int pageCount)
        {
            pageCount = (int)Math.Ceiling((double)_course.Helps.Count / pageSize);
            return _course.Helps
                .OrderByDescending(help => help.UpdateTime)
                .Skip(pageSize * (page - 1))
                .Take(pageSize)
                .ToList();
        }

        /// <summary>
        /// 根据指定页容量返回闲聊信息
        /// </summary>
        /// <param name="page">页码</param>
        /// <param name="pageSize">每页容量</param>
        /// <param name="pageCount">返回总页数</param>
        /// <returns>求助闲聊列表</returns>
        public List<Chat> GetChats(int page, int pageSize, out int pageCount)
        {
            pageCount = (int)Math.Ceiling((double)_course.Chats.Count / pageSize);
            return _course.Chats
                .OrderByDescending(help => help.UpdateTime)
                .Skip(pageSize * (page - 1))
                .Take(pageSize)
                .ToList();
        }

        /// <summary>
        /// 查找求助信息
        /// </summary>
        /// <param name="keywords">关键字</param>
        /// <param name="page">页码</param>
        /// <param name="pageSize">每页容量</param>
        /// <param name="pageCount">返回总页数</param>
        /// <returns>查找结果</returns>
        public List<Help> SearchHelps(string keywords, int page, int pageSize, out int pageCount)
        {
            var result = _course.Helps.AsEnumerable();
            result = keywords.Split(' ')
                .Aggregate(result,
                    (current, keyword) =>
                        current.Where(help =>
                            help.UserName.Contains(keyword)
                            || help.Content.Contains(keyword)
                            || help.HelpReplys.Count(reply =>
                                reply.UserName.Contains(keyword)
                                || reply.Content.Contains(keyword)) > 0))
                .OrderByDescending(help => help.UpdateTime);
            var tmp = result.ToList();
            pageCount = (int)Math.Ceiling((double)tmp.Count / pageSize);
            result = tmp.Skip(pageSize * (page - 1)).Take(pageSize);
            return result.ToList();
        }

        /// <summary>
        /// 查找闲聊信息
        /// </summary>
        /// <param name="keywords">关键字</param>
        /// <param name="page">页码</param>
        /// <param name="pageSize">每页容量</param>
        /// <param name="pageCount">返回总页数</param>
        /// <returns>查找结果</returns>
        public List<Chat> SearchChats(string keywords, int page, int pageSize, out int pageCount)
        {
            var result = _course.Chats.AsEnumerable();
            result = keywords.Split(' ')
                .Aggregate(result,
                    (current, keyword) =>
                        current.Where(chat =>
                            chat.UserName.Contains(keyword)
                            || chat.Content.Contains(keyword)
                            || chat.ChatReplys.Count(reply =>
                                reply.UserName.Contains(keyword)
                                || reply.Content.Contains(keyword)) > 0))
                .OrderByDescending(chat => chat.UpdateTime);
            var tmp = result.ToList();
            pageCount = (int)Math.Ceiling((double)tmp.Count / pageSize);
            result = tmp.Skip(pageSize * (page - 1)).Take(pageSize);
            return result.ToList();
        }

        /// <summary>
        /// 我的求助
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="page">页码</param>
        /// <param name="pageSize">每页容量</param>
        /// <param name="pageCount">返回总页数</param>
        /// <returns>查找结果</returns>
        public List<Help> GetMyHelps(string userId, int page, int pageSize, out int pageCount)
        {
            var result = _course.Helps.Where(help =>
                                             help.UserId == userId
                                             || help.HelpReplys.Count(reply => reply.UserId == userId) > 0)
                                             .OrderByDescending(help => help.UpdateTime);
            pageCount = result.Count();
            return result.Skip(pageSize * (page - 1)).Take(pageSize).ToList();
        }

        /// <summary>
        /// 我的闲聊
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="page">页码</param>
        /// <param name="pageSize">每页容量</param>
        /// <param name="pageCount">返回总页数</param>
        /// <returns>查找结果</returns>
        public List<Chat> GetMyChats(string userId, int page, int pageSize, out int pageCount)
        {
            var result = _course.Chats.Where(chat =>
                                             chat.UserId == userId
                                             || chat.ChatReplys.Count(reply => reply.UserId == userId) > 0)
                                             .OrderByDescending(help => help.UpdateTime);
            pageCount = result.Count();
            return result.Skip(pageSize * (page - 1)).Take(pageSize).ToList();
        }

        /// <summary>
        /// 发布课程地点
        /// </summary>
        /// <param name="place">课程地点</param>
        /// <param name="uid">用户ID</param>
        /// <param name="username">用户名</param>
        public void PulishPlace(string place, string uid, string username)
        {
            var coursePlace = new CoursePlcace
                                  {
                                      EditorId = uid,
                                      EditorName = username,
                                      EditTime = DateTime.Now,
                                      Place = place
                                  };
            _course.CoursePlaces.Add(coursePlace);
            using (var context = new ModelContainer())
            {
                context.Courses.ApplyChanges(_course);
                context.SaveChanges();
                _course.AcceptChanges();
            }
        }

        /// <summary>
        /// 判断课程是否有地点
        /// </summary>
        /// <returns>判断结果</returns>
        public bool HasPlace()
        {
            return _course.CoursePlaces.Count > 0;
        }

        /// <summary>
        /// 添加闲聊回复
        /// </summary>
        /// <param name="chatReply">ChatReply</param>
        public void HelpReply(ChatReply chatReply)
        {
            var chat = _course.Chats.Single(h => h.ID == chatReply.ChatID);
            chat.UpdateTime = DateTime.Now;
            chat.MarkAsModified();
            using (var context = new ModelContainer())
            {
                context.ChatReplys.ApplyChanges(chatReply);
                context.Chats.ApplyChanges(chat);
                context.SaveChanges();
            }
        }

        /// <summary>
        /// 添加求助回复
        /// </summary>
        /// <param name="helpReply">HelpReply</param>
        public void HelpReply(HelpReply helpReply)
        {
            var help = _course.Helps.Single(h => h.ID == helpReply.HelpID);
            help.UpdateTime = DateTime.Now;
            help.MarkAsModified();
            using (var context = new ModelContainer())
            {
                context.HelpReplys.ApplyChanges(helpReply);
                context.Helps.ApplyChanges(help);
                context.SaveChanges();
            }
        }

        /// <summary>
        /// 添加求助
        /// </summary>
        /// <param name="content">内容</param>
        /// <param name="uid">用户ID</param>
        /// <param name="name">用户姓名</param>
        /// <param name="pic">用户头像</param>
        public void PostHelp(string content, string uid, string name, string pic)
        {
            var help = new Help
                           {
                               UserId = uid,
                               UserName = name,
                               UserPic = pic,
                               Time = DateTime.Now,
                               UpdateTime = DateTime.Now,
                               Content = content
                           };
            _course.Helps.Add(help);
            _course.MarkAsModified();
            using (var context = new ModelContainer())
            {
                context.Courses.ApplyChanges(_course);
                context.SaveChanges();
                _course.AcceptChanges();
            }
        }

        /// <summary>
        /// 添加闲聊
        /// </summary>
        /// <param name="content">内容</param>
        /// <param name="uid">用户ID</param>
        /// <param name="name">用户姓名</param>
        /// <param name="pic">用户头像</param>
        public void PostChat(string content, string uid, string name, string pic)
        {
            var chat = new Chat
            {
                UserId = uid,
                UserName = name,
                UserPic = pic,
                Time = DateTime.Now,
                UpdateTime = DateTime.Now,
                Content = content
            };
            _course.Chats.Add(chat);
            _course.MarkAsModified();
            using (var context = new ModelContainer())
            {
                context.Courses.ApplyChanges(_course);
                context.SaveChanges();
                _course.AcceptChanges();
            }
        }
    }
}